package com.qf.springboot.service.impl;

import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.springboot.dao.UserDao;
import com.qf.springboot.entity.User;
import com.qf.springboot.service.UserService;
import com.qf.springboot.utils.Constants;
import com.qf.springboot.vo.ResultVo;
import com.qf.springboot.vo.TableVo;
import com.qf.springboot.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {
    @Autowired
    private UserDao userDao;
    private ResultVo resultVo = null;

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public User login(String username, String password) {
        log.debug("userService层调用了");
        password = DigestUtil.md5Hex(password);
        return userDao.loginByUsernameAndPassword(username, password);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public User checkCookieUsernameAndPassword(String username, String password) {
        return userDao.loginByUsernameAndPassword(username, password);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultVo delUserByIds(Integer[] ids) {
        Integer flag = userDao.delUserByIds(ids);
        if (flag > 0) {
            return new ResultVo(1, "删除成功");
        }
        return new ResultVo(-1, "删除失败");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultVo addUser(User user) {
        user.setPassword(DigestUtil.md5Hex(user.getPassword()));
        Integer flag = userDao.insertUser(user);
        if (flag > 0) {
            return new ResultVo(1, "添加成功");
        }
        return new ResultVo(-1, "添加失败");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultVo updateUser(User user) {
        String password = user.getPassword();
        User dbUser = userDao.getUserById(user.getId());
        if (!dbUser.getPassword().equals(password)) {
            user.setPassword(DigestUtil.md5Hex(user.getPassword()));
        }
        Integer flag = userDao.updateUser(user);
        if (flag > 0) {
            return new ResultVo(1, "修改成功");
        }
        return new ResultVo(-1, "修改失败");
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<User> findAllUsers() {
        List<User> users = userDao.selectAllUsers();
        return users;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public TableVo<User> getUsersByContdition(Integer page, Integer limit, UserVo userVo) {
        Page mapPage = new Page(page, limit);
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        if (userVo.getUsername() != null && userVo.getUsername() != "") {
            userQueryWrapper.eq("name", userVo.getUsername());
        }
        if (userVo.getSex() != null) {
            userQueryWrapper.eq("sex", userVo.getSex());
        }
        if (userVo.getBirthday() != null) {
            userQueryWrapper.eq("birthday", userVo.getBirthday());
        }
        userDao.selectMapsPage(mapPage, userQueryWrapper);
        List userList = mapPage.getRecords();
        long total = mapPage.getTotal();
        /*PageHelper.startPage(page, limit);
        List<User> users = userDao.getUsersByContdition(userVo);
        PageInfo<User> pageInfo = new PageInfo<>(users);*/
        TableVo<User> tableVo = null;
        if (userList != null) {
            tableVo = new TableVo<>(0, "OK", (int) total, userList);
        } else {
            tableVo = new TableVo<>(-1, "ERROR", (int) total, null);
        }
        return tableVo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultVo addUserByFile(MultipartFile file) {
        String line;
        BufferedReader br = null;
        List<User> list = new ArrayList<>();
        try {
            br = new BufferedReader(new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8));
            while ((line = br.readLine()) != null) {
                if (!line.equals("")) {
                    User csvUser = User.cvsToUser(line);
                    boolean flag = this.checkUsername(csvUser.getName());
                    if (!flag) {
                        list.add(csvUser);
                    }
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                br.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        Integer flag = 0;
        if (list.size() > 0) {
            flag = userDao.addUserByList(list);
        }
        if (flag > 0) {
            return new ResultVo(1, "添加成功");
        }
        return new ResultVo(-1, "添加失败");
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public boolean checkUsername(String username) {
        return userDao.getUserByUsername(username) != null;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultVo register(UserVo userVo, String realPath) {
        try {
            File dir = new File(realPath);
            if (!dir.exists()) {
                dir.mkdir();
            }
            final String randomName = UUID.randomUUID().toString();
            final String originalFilename = userVo.getImg().getOriginalFilename();
            final String extension = FilenameUtils.getExtension(originalFilename);
            String finalFileName = randomName + "." + extension;
            String finalFilePath = realPath + File.separator + finalFileName;
            log.debug("用户头像存放的路径为{}", finalFilePath);
            User user = new User();
            BeanUtils.copyProperties(userVo, user);
            user.setId(null);
            user.setName(userVo.getUsername());
            user.setRegistTime(new Date());
            user.setAuth("normal");
            user.setPhotopath(finalFileName);
            user.setPassword(DigestUtil.md5Hex(userVo.getPassword()));
            userDao.insertUser(user);
            userVo.getImg().transferTo(new File(finalFilePath));
            resultVo = new ResultVo(Constants.SUCCESS_CODE, "注册成功");
        } catch (IOException e) {
            resultVo = new ResultVo(Constants.FAIL_CODE, "注册失败");
            throw new RuntimeException(e);
        } finally {
            return resultVo;
        }

    }

    /**
     * 分页查询用户数据
     *
     * @param page  页号
     * @param limit 页大小
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public TableVo<User> getAllUsersByPage(Integer page, Integer limit) {
        /*log.debug("查询用户：page={} limit={}", page, limit);

        //查询当前页的用户数据
        PageHelper.startPage(page, limit);
        List<User> users = userDao.selectAllUsers();
        //查询user总条数
        PageInfo pageInfo = new PageInfo(users);
        long count = pageInfo.getTotal();
        TableVo<User> tableVo = new TableVo<>(0, "OK", (int) count, users);
        return tableVo;*/
        return null;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public ResultVo selectAndClearAllPhotopath() {
        File dir = new File(Constants.UPLOAD_PATH);
        File[] files = dir.listFiles();
        List<String> list = Arrays.stream(files)
                .filter(File::isFile)
                .map(File::getName)
                .collect(Collectors.toList());
        log.debug("所有头像的文件list={}", list);
        List<User> users = userDao.selectAllUsers();
        List<String> dbList = users.stream().map(User::getPhotopath).collect(Collectors.toList());
        log.debug("数据库头像的文件dblist={}", dbList);
        list.removeAll(dbList);
        log.debug("要删除的头像list={}", list);
        if (list.size() > 0) {
            list.forEach(filename -> {
                String filepath = Constants.UPLOAD_PATH + File.separator + filename;
                File file = new File(filepath);
                file.delete();
            });
            return new ResultVo(Constants.SUCCESS_CODE, "清理成功");
        }
        return new ResultVo(Constants.SUCCESS_CODE, "没有文件需要删除");
    }
}
